getPCdata<-function (schema="bmde", resource="prbo", type="pointcount", dsn="bmde.readme", study.area="ALL", species="ALL", min.date, max.date, all.data=TRUE, database="PRBOdb", ... ) {
	schema<-casefold(schema)
	resource<-casefold(resource)
	type<-casefold(type)
	query.table<-"ERROR"
	#TODO: Should do some error checking on the arguments passed -- e.g. you really can't have resource='ebird' without also having schema='bmde'
	#TODO: should have a lookup table that can take the resource and type information (and schema if needed) that returns the correct table name (e.g. ebird, pointcount --> ebird_v138)
	# but for now I'll just do this right here:
	if (schema=='bmde') {
		query.table<-ifelse(resource=='prbo','digir_v138',
				ifelse(resource=='bbs','bbs_v138',
						ifelse(resource=='ebird','ebird_v138','ERROR')))
	}
	if (schema=='prbodb') {
		query.table<-ifelse(resource=='prbo','pcflatfile',
				ifelse(resource=='bbs','ERROR',
						ifelse(resource=='ebird','ERROR','ERROR')))
	}
	query.end<-""
# For future work, make each filter a separate variable
	query.project=""
	query.study.area=""
	query.species=""
	query.mindate=""
	query.maxdate=""
	if (schema=="bmde") {
		if (study.area[1] !="ALL") {
			SamplingUnits<-study.area
			SamplingUnitID<-paste("'",SamplingUnits,"'",sep="",collapse=",")
#            SamplingUnitID<-SamplingUnits
			query.study.area<-ifelse(resource!="ebird",
					paste(paste("AND RouteIdentifier in (",paste(SamplingUnitID,sep="",collapse=","),")",sep=""),query.transect),
					paste(paste("AND ObservationCount>0 AND SurveyAreaIdentifier in (",paste(SamplingUnitID,sep="",collapse=","),")",sep=""),query.transect)
			)
		} 
		if (species[1] !="ALL") {
			SpeciesList<-paste("'",species,"'",sep="",collapse=",")
			#species.sci<-GetSpeciesName(spec=species,sci.name=TRUE, batch=TRUE, ...)
			#SpeciesList<-paste("'",species.sci,"'",sep="",collapse=",")
			query.species<-paste(paste("AND CommonName in (",SpeciesList,")",sep=""),query.end)
		}
		
		query.end<-paste(query.end,"ORDER BY transect_name,point,year,month,day")
		query<- paste(  "SELECT ProjectCode as project, ScientificName as scientific_name, CommonName as species, YearCollected as year, MonthCollected as month, DayCollected as day, JulianDay as julian_day, RouteIdentifier as transect, SurveyAreaIdentifier as point, StateProvince as state, County as region, TimeCollected as time, SamplingEventIdentifier as visit, Locality as transect_name, sum(ObservationCount) as observed_count",
				"FROM",query.table,
				"WHERE ScientificName <> Family AND ScientificName <> Genus",  # removes birds identified to family or genus only
				"AND Locality IS NOT NULL AND SurveyAreaIdentifier IS NOT NULL AND CommonName <>'' AND ScientificName IS NOT NULL",
				query.transect, query.species,
				"GROUP BY ScientificName, YearCollected, MonthCollected, DayCollected, RouteIdentifier, SurveyAreaIdentifier" 
		)
		query<-paste(query,query.end)
		pcdata<-sqlQuery(db<-PRBOdbConnect(group=dsn, ...),query)
		close(db)
#TODO: Right now I am going to assume an ebird point is a transect, because I don't do analyses at the point level yet.. someday this can get "fixed"
		if (resource=='ebird') pcdata$transect<-pcdata$point 
		if(nrow(pcdata)==0) stop("No records retrieved")
		suppressWarnings(pcdata[is.na(as.numeric(pcdata$point))==TRUE,]$point<-substr(pcdata[is.na(as.numeric(pcdata$point))==TRUE,]$point,1,4))
		# pcdata$spec<-GetSpeciesCode(pcdata$scientific_name,sci.name=TRUE,batch=TRUE)
		# pcdata$species<-GetSpeciesName(pcdata$spec,batch=TRUE)
		pcdata$date<-with(pcdata,as.Date(paste(year,month,day,sep=""),"%Y%m%d"))
#        pcdata$visit<-DetermineVisits(data=pcdata)
		#  pcdata$transect<-GetPointCountTransectID(pcdata$point,batch=TRUE)
	} else { #schema == PRBOdb
		if (transect[1] != "ALL") {
			query.end<-paste(paste("AND transect in (",paste("'",transect,"'",sep="",collapse=","),")",sep=""),"ORDER BY transect,point,year,month,day")
		} else {
			query.end<-"ORDER BY transect,point,year,month,day"
		}
		if (species[1] !="ALL") {
			SpeciesList<-paste("'",species,"'",sep="",collapse=",")
			query.end<-paste(paste("AND SPEC in (",SpeciesList,")",sep=""),query.end)
		}
		query<-paste(   "SELECT t1.spec,substr(t1.data,1,1) as detection, substr(t1.data,2,3) as distance, t1.state, t1.region as county, t1.station as transect, t1.initials as observer, t1.visit, substr(t1.date,1,2) as month, substr(t1.date,4,2) as day, substr(t1.date,7,4) as year, STR_TO_DATE(t1.date,'%m/%d/%Y') as date, t1.site as point, t1.time, t1.hab, t2.SamplingUnitName as transect_name",
				"FROM PcFlatFormat t1, SamplingUnit t2",
				"WHERE t1.station=t2.PointCountTransectID"
		)
		query<-paste(query,query.end)
		pcdata<-sqlQuery(db<-PRBOdbConnect(group=dsn,...),query)
		close(db)
		if(nrow(pcdata)==0) stop("No records retrieved")
		pcdata$species<-GetSpeciesName(pcdata$spec,batch=TRUE)
		pcdata$scientific_name<-GetSpeciesName(pcdata$spec,sci.name=TRUE,batch=TRUE)
		if (nrow(pcdata[is.na(pcdata$species)==TRUE,]) >0 ) warning("NA's were generated during query for species names.  This is most likely due to the fact that currently there are 2 codes considered current for a particular species.")
	}
	pcdata$transect<-factor(pcdata$transect)
	pcdata$point<-factor(pcdata$point)
	pcdata$visit<-factor(pcdata$visit)
	return(pcdata)
}


DetermineVisits <- function(data=NULL, same.visit=7) {
	if (is.null(data)==TRUE) stop("A data file is required.")
	data$visit<-0
	for (bygrp in levels(factor(paste(data$SamplingUnitID,data$point,data$year,sep="")))) {
		visit<-1
		j<-nrow(data[paste(data$SamplingUnitID,data$point,data$year,sep="")==bygrp,])
		if (j>0) {
			for (VisitDate in levels(factor(data[paste(data$SamplingUnitID,data$point,data$year,sep="")==bygrp,]$date))) {
				if (nrow(data[paste(data$SamplingUnitID,data$point,data$year,sep="")==bygrp & abs(as.numeric(data$date-as.Date(VisitDate))) <= same.visit & data$visit==0,])>0) {
					data[paste(data$SamplingUnitID,data$point,data$year,sep="")==bygrp & abs(as.numeric(data$date-as.Date(VisitDate))) <= same.visit & data$visit==0,]$visit<-visit
					visit<-visit+1
				}
			}
		}
	}
	return(data$visit)
}

EstimateSpeciesRichness<- function(data=NULL, min.month=3, max.month=8, year=NULL, ...) {
	if (is.null(data)==TRUE) stop("A data file is required.")
	data<-data[as.numeric(data$month)>=min.month & as.numeric(data$month)<=max.month,]
	if (is.null(year)==FALSE) data<-data[data$year %in% year,]
	return(with((t<-data.frame(with(data,table(year,transect_name,species))))[t$Freq>0,],table(year,transect_name)))
}

EstimateAbundance<-function(data=NULL, min.month=3, max.month=8, year=NULL, transect="ALL", species="ALL", group.transect=FALSE,...) {
	# take a look at the cast command.
	if (is.null(data)==TRUE) stop("A data file is required.")
	#filter data based on request
	data<-data[as.numeric(data$month)>=min.month & as.numeric(data$month)<=max.month,]
	if (group.transect==TRUE) data$transect<-factor(paste(paste(transect,collapse=","),"transects combined"))
	if (is.null(year)==FALSE) data<-data[data$year %in% year,]
	effort.table<-NULL
	for (Year in levels(factor(data$year))) {
		for (Transect in levels(data[data$year==Year,]$transect)) {
			for (Point in levels(factor(data[data$year==Year & data$transect==Transect,]$point))) {
				for (Visit in levels(factor(data[data$year==Year & data$transect==Transect & data$point==Point,]$visit))) {
					effort.table<-rbind(effort.table,c(Transect,Point,Visit,Year,with(data[data$year==Year & data$transect==Transect & data$point==Point & data$visit==Visit,][1,],c(as.character(state),as.character(region),as.character(transect_name),month,day,julian_day))))
				}
			}
		}
	}
	effort.table<-data.frame(effort.table)
	names(effort.table)<-c("transect","point","visit","year","state","region","transect_name","month","day","julian_day")
	if (species != "ALL") data<-data[data$species %in% species,]
	if (transect != "ALL") data<-data[data$transect %in% transect,]
	data$species<-factor(data$species)
	temp<-data.frame()
	for (Transect in levels(factor(data$transect))) {
		data1<-data[data$transect==Transect,]
		for (Year in levels(factor(data1$year))) {
			data2<-data1[data1$year==Year,]
			full.table<-merge(data2,effort.table[effort.table$transect==Transect & effort.table$year==Year,],all.y=TRUE)
			full.table$observed_count<-ifelse(is.na(full.table$observed_count)==TRUE,0,full.table$observed_count)
			full.table$species<-species
			full.table$scientific_name<-ifelse(species=="ALL","ALL",as.character(data[data$species==species,][1,]$scientific_name))
			# Mean Abundance is currently estimated as the Average of the point averages, and the point averages are the averages of the counts on all visits in the given year's dataset
			MeanAbund<-aggregate((t2<-aggregate(full.table$observed_count,list(point=full.table$point,species=full.table$species),mean))$x,list(species=t2$species),mean)
			names(MeanAbund)[names(MeanAbund)=="x"]<-"MeanAbund"
			#Variance right now is only the variance around the point level estimates (it does not include variation in the point estimates (from the multiple visits))
			VarAbund<-aggregate(t2$x,list(species=t2$species),var)
			names(VarAbund)[names(VarAbund)=="x"]<-"VarAbund"
			# This I believe needs to be fixed (at least checked) --- does not "feel" right
			SampleSize<-aggregate(!is.na(t2$x),list(species=t2$species),sum)
			names(SampleSize)[names(SampleSize)=="x"]<-"SampleSize"
			temp1<-merge(merge(MeanAbund,VarAbund),SampleSize)
			temp1$year<-Year
			temp1$seAbund<-sqrt(temp1$VarAbund/temp1$SampleSize)
			temp1$transect<-Transect
			temp1$transect_name<-effort.table[effort.table$transect==Transect,]$transect_name[1]
			# temp1$transect_name<-GetTransectName(Transect)[1] # in case there is more than 1 choice
			temp<-rbind(temp,temp1)
		}
	}
#    if (species=="ALL") species<-levels(data$species)
#    temp<-temp[temp$species %in% species,]
	return(temp)
}
